home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / hobbes3 / rect.asm < prev    next >
Assembly Source File  |  1992-08-26  |  23KB  |  675 lines

  1. include hobbes.inc
  2. include extrn.inc
  3.  
  4. .DATA
  5.  
  6. ; Plane masks for clipping left and right edges of rectangle
  7. LeftClipPlaneMask       db      00fh,00eh,00ch,008h
  8. RightClipPlaneMask      db      00fh,001h,003h,007h
  9.  
  10.  
  11. .CODE
  12.  
  13.  
  14. ;----------------------------------------------------------------------------
  15. ; void RectangleFillAligned(int x0, int y0, int x1, int y1, COLOR);
  16. ;
  17.         public  _RectangleFillAligned
  18. _RectangleFillAligned proc
  19. ARG X0, Y0, X1, Y1, COLOR
  20.         push    bp
  21.         mov     bp,sp
  22.         push    ds
  23.         mov     ax,@data
  24.         mov     ds,ax
  25.  
  26.         mov     es,_ModeX_Segment   ; point ES:DI to the first rectangle pixel's address
  27.         push    si
  28.         push    di
  29.  
  30.         mov     dx,SC_INDEX     ; set the Sequence Controller Index to
  31.         mov     al,MAP_MASK     ;   point to the Map Mask register
  32.         out     dx,al
  33.         inc     dx              ; point DX to the SC Data register
  34.         mov     al,0fh          ; write to all planes
  35.         out     dx,al           ; set the mask
  36.  
  37.         cld
  38.         mov     di,Y0
  39.         shl     di,1            ; address of the row offset word
  40.         mov     di,word ptr _RowOffset[di]
  41.         mov     ax,X0
  42.         shr     ax,2            ; X/4 = offset of pixel in scan line
  43.         add     di,ax           ; final offset of pixel in page
  44.  
  45.         mov     cx,X1           ; calculate # of addresses across rect
  46.         mov     bx,X0
  47.         and     bx,not 011b
  48.         sub     cx,bx
  49.         shr     cx,2    ; # of addresses across box to fill - 1
  50.         inc     cx      ; # of addresses across box to fill
  51.         mov     si,cx   ; save a copy in SI
  52.         mov     bx,Y1
  53.         sub     bx,Y0   ; BX = height of rectangle - 1
  54.         mov     al,byte ptr COLOR       ; color with which to fill
  55.         mov     ah,al
  56.         mov     bp,_Virtual_Width_Addr   ; stack frame isn't needed any more
  57.         sub     bp,cx   ; distance from end of one scan line to start of next
  58. @@BoxAligned_RowsLoop:
  59.         shr     cx,1    ; get the number of pixel pairs
  60.         rep     stosw   ; draw the middle addresses eight pixels apiece
  61.         adc     cx,0    ; odd number of pixels?
  62.         rep     stosb   ; rep used to draw the last pixel ONLY if necessary
  63.         add     di,bp   ; point to the start of the next scan line of
  64.                         ;   the rectangle
  65.         mov     cx,si   ; retrieve width in addresses
  66.         dec     bx      ; count down scan lines
  67.         jnl     @@BoxAligned_RowsLoop
  68. @@BoxAligned_Done:
  69.         pop     di
  70.         pop     si
  71.         pop     ds
  72.         pop     bp
  73.         ret
  74. _RectangleFillAligned endp
  75.  
  76.  
  77.  
  78.  
  79. ;----------------------------------------------------------------------------
  80. ;    void RectangleFill(int StartX, int StartY, int EndX, int EndY, COLOR);
  81.  
  82.         public  _RectangleFill
  83. _RectangleFill     proc    far
  84. ARG StartX:WORD, StartY:WORD, EndX:WORD, EndY:WORD, Color:WORD
  85.         push    bp
  86.         mov     bp,sp
  87.         push    si
  88.         push    di
  89.         push    ds
  90.         mov        ax,@data
  91.         mov        ds,ax
  92.  
  93.         cld
  94.         mov     ax,_Virtual_Width_Addr
  95.         mul     StartY ;offset in page of top rectangle scan line
  96.         mov     di,StartX
  97.         shr     di,1    ;X/4 = offset of first rectangle pixel in scan
  98.         shr     di,1    ; line
  99.         add     di,ax   ;offset of first rectangle pixel in page
  100.         add     di,_Display_Offset ;offset of first rectangle pixel in
  101.                                     ; display memory
  102.         mov     ax,_ModeX_Segment   ;point ES:DI to the first rectangle
  103.         mov     es,ax           ; pixel's address
  104.         mov     dx,SC_INDEX ;set the Sequence Controller Index to
  105.         mov     al,MAP_MASK ; point to the Map Mask register
  106.         out     dx,al
  107.         inc     dx      ;point DX to the SC Data register
  108.         mov     si,StartX
  109.         and     si,0003h                 ;look up left edge plane mask
  110.         mov     bh,LeftClipPlaneMask[si] ; to clip & put in BH
  111.         mov     si,EndX
  112.         and     si,0003h                  ;look up right edge plane
  113.         mov     bl,RightClipPlaneMask[si] ; mask to clip & put in BL
  114.  
  115.         mov     cx,EndX    ;calculate # of addresses across rect
  116.         mov     si,StartX
  117.         cmp     cx,si
  118.         jle     @@FillDone        ;skip if 0 or negative width
  119.         dec     cx
  120.         and     si,not 011b
  121.         sub     cx,si
  122.         shr     cx,1
  123.         shr     cx,1    ;# of addresses across rectangle to fill - 1
  124.         jnz     @@MasksSet ;there's more than one byte to draw
  125.         and     bh,bl   ;there's only one byte, so combine the left
  126.                         ; and right edge clip masks
  127. @@MasksSet:
  128.         mov     si,EndY
  129.         sub     si,StartY  ;BX = height of rectangle
  130.         jle     @@FillDone        ;skip if 0 or negative height
  131.         mov     ah,byte ptr Color ;color with which to fill
  132.         mov     bp,_Virtual_Width_Addr ;stack frame isn't needed any more
  133.         sub     bp,cx   ;distance from end of one scan line to start
  134.         dec     bp      ; of next
  135. @@FillRowsLoop:
  136.         push    cx      ;remember width in addresses - 1
  137.         mov     al,bh   ;put left-edge clip mask in AL
  138.         out     dx,al   ;set the left-edge plane (clip) mask
  139.         mov     al,ah   ;put color in AL
  140.         stosb           ;draw the left edge
  141.         dec     cx      ;count off left edge byte
  142.         js      @@FillLoopBottom ;that's the only byte
  143.         jz      @@DoRightEdge ;there are only two bytes
  144.         mov     al,00fh ;middle addresses are drawn 4 pixels at a pop
  145.         out     dx,al   ;set the middle pixel mask to no clip
  146.         mov     al,ah   ;put color in AL
  147.         rep     stosb   ;draw the middle addresses four pixels apiece
  148. @@DoRightEdge:
  149.         mov     al,bl   ;put right-edge clip mask in AL
  150.         out     dx,al   ;set the right-edge plane (clip) mask
  151.         mov     al,ah   ;put color in AL
  152.         stosb           ;draw the right edge
  153. @@FillLoopBottom:
  154.         add     di,bp   ;point to the start of the next scan line of
  155.                         ; the rectangle
  156.         pop     cx      ;retrieve width in addresses - 1
  157.         dec     si      ;count down scan lines
  158.         jnz     @@FillRowsLoop
  159. @@FillDone:
  160.  
  161.         pop        ds
  162.         pop     di
  163.         pop     si
  164.         pop     bp
  165.         ret
  166. _RectangleFill endp
  167.  
  168.  
  169.  
  170.  
  171. ;----------------------------------------------------------------------------
  172. ; void RectangleFillClip(int StartX, int StartY, int EndX, int EndY, COLOR);
  173.  
  174.         public  _RectangleFillClip
  175. _RectangleFillClip     proc    far
  176. ARG StartX:WORD, StartY:WORD, EndX:WORD, EndY:WORD, Color:WORD
  177.         push    bp
  178.         mov     bp,sp
  179.         push    si
  180.         push    di
  181.         push    ds
  182.         mov        ax,@data
  183.         mov        ds,ax
  184.  
  185.         ; clip it
  186.         ; yeah, it's may be kinda cheezy, but it's still fairly quick
  187.         ; (plus, it took about 5min :-])
  188. @@_ClipLeft:
  189.         mov        ax, StartX
  190.         cmp        ax, _ClipLeft
  191.         jg        @@_ClipRight
  192.         mov        ax, _ClipLeft
  193.         mov        StartX,ax
  194. @@_ClipRight:
  195.         mov        ax, EndX
  196.         cmp        ax, _ClipRight
  197.         jle        @@_ClipTop
  198.         mov        ax, _ClipRight
  199.         mov        EndX, ax
  200. @@_ClipTop:
  201.         mov        ax, StartY
  202.         cmp        ax, _ClipTop
  203.         jg        @@_ClipBottom
  204.         mov        ax, _ClipTop
  205.         mov        StartY, ax
  206. @@_ClipBottom:
  207.         mov        ax, EndY
  208.         cmp        ax, _ClipBottom
  209.         jle        @@ClipDone
  210.         mov        ax, _ClipBottom
  211.         mov        EndY, ax
  212.  
  213. @@ClipDone:
  214.         cld
  215.         mov        di,StartY
  216.         shl        di,1
  217.         mov        ax,word ptr _RowOffset[di]
  218.         mov     di,StartX
  219.         shr     di,1        ;X/4 = offset of first rectangle pixel in scan
  220.         shr     di,1        ; line
  221.         add     di,ax       ;offset of first rectangle pixel in page
  222.         add     di,_Display_Offset        ;offset of first rectangle pixel in
  223.                                     ; display memory
  224.         mov     ax,_ModeX_Segment       ;point ES:DI to the first rectangle
  225.         mov     es,ax           ; pixel's address
  226.         mov     dx,SC_INDEX     ;set the Sequence Controller Index to
  227.         mov     al,MAP_MASK     ; point to the Map Mask register
  228.         out     dx,al
  229.         inc     dx              ;point DX to the SC Data register
  230.         mov     si,StartX
  231.         and     si,0003h                 ;look up left edge plane mask
  232.         mov     bh,LeftClipPlaneMask[si] ; to clip & put in BH
  233.         mov     si,EndX
  234.         and     si,0003h                  ;look up right edge plane
  235.         mov     bl,RightClipPlaneMask[si] ; mask to clip & put in BL
  236.  
  237.         mov     cx,EndX                ;calculate # of addresses across rect
  238.         mov     si,StartX
  239.         cmp     cx,si
  240.         jle     @@FillDone            ;skip if 0 or negative width
  241.         dec     cx
  242.         and     si,not 011b
  243.         sub     cx,si
  244.         shr     cx,1
  245.         shr     cx,1        ;# of addresses across rectangle to fill - 1
  246.         jnz     @@MasksSet     ;there's more than one byte to draw
  247.         and     bh,bl       ;there's only one byte, so combine the left
  248.                             ; and right edge clip masks
  249. @@MasksSet:
  250.         mov     si,EndY
  251.         sub     si,StartY  ;BX = height of rectangle
  252.         jle     @@FillDone        ;skip if 0 or negative height
  253.         mov     ah,byte ptr Color ;color with which to fill
  254.         mov     bp,_Virtual_Width_Addr ;stack frame isn't needed any more
  255.         sub     bp,cx   ;distance from end of one scan line to start
  256.         dec     bp      ; of next
  257. @@FillRowsLoop:
  258.         push    cx      ;remember width in addresses - 1
  259.         mov     al,bh   ;put left-edge clip mask in AL
  260.         out     dx,al   ;set the left-edge plane (clip) mask
  261.         mov     al,ah   ;put color in AL
  262.         stosb           ;draw the left edge
  263.         dec     cx      ;count off left edge byte
  264.         js      @@FillLoopBottom ;that's the only byte
  265.         jz      @@DoRightEdge ;there are only two bytes
  266.         mov     al,00fh ;middle addresses are drawn 4 pixels at a pop
  267.         out     dx,al   ;set the middle pixel mask to no clip
  268.         mov     al,ah   ;put color in AL
  269.         rep     stosb   ;draw the middle addresses four pixels apiece
  270. @@DoRightEdge:
  271.         mov     al,bl   ;put right-edge clip mask in AL
  272.         out     dx,al   ;set the right-edge plane (clip) mask
  273.         mov     al,ah   ;put color in AL
  274.         stosb           ;draw the right edge
  275. @@FillLoopBottom:
  276.         add     di,bp   ;point to the start of the next scan line of
  277.                         ; the rectangle
  278.         pop     cx      ;retrieve width in addresses - 1
  279.         dec     si      ;count down scan lines
  280.         jnz     @@FillRowsLoop
  281. @@FillDone:
  282.         pop        ds
  283.         pop     di
  284.         pop     si
  285.         pop     bp
  286.         ret
  287. _RectangleFillClip endp
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294. ;----------------------------------------------------------------------------
  295. ; void RectangleFillPattern(int StartX, int StartY, int EndX, int EndY, PATTERN);
  296.  
  297.         public  _RectangleFillPattern
  298. _RectangleFillPattern proc    far
  299. ARG StartX:WORD, StartY:WORD, EndX:WORD, EndY:WORD, Pattern:DWORD
  300. LOCAL NextScanOffset:WORD, RectAddrWidth:WORD, Height:WORD = LocalStack
  301.         push    bp
  302.         mov     bp,sp
  303.         sub     sp,LocalStack
  304.         push    si
  305.         push    di
  306.         push     ds
  307.  
  308.  
  309.         cld
  310.         mov     ax,_ModeX_Segment        ;point ES to display memory
  311.         mov     es,ax
  312.                                 ;copy pattern to display memory buffer
  313. ;        mov     si,Pattern         ;point to pattern to fill with
  314.         mov     di,_Pattern_Offset ;point ES:DI to pattern buffer
  315.         lds        si,Pattern
  316.         mov     dx,SC_INDEX     ;point Sequence Controller Index to
  317.         mov     al,MAP_MASK     ; Map Mask
  318.         out     dx,al
  319.         inc     dx              ;point to SC Data register
  320.         mov     cx,4            ;4 pixel quadruplets in pattern
  321. @@DownloadPatternLoop:
  322.         mov     al,1            ;
  323.         out     dx,al           ;select plane 0 for writes
  324.         movsb                   ;copy over next plane 0 pattern pixel
  325.         dec     di              ;stay at same address for next plane
  326.         mov     al,2            ;
  327.         out     dx,al           ;select plane 1 for writes
  328.         movsb                   ;copy over next plane 1 pattern pixel
  329.         dec     di              ;stay at same address for next plane
  330.         mov     al,4            ;
  331.         out     dx,al           ;select plane 2 for writes
  332.         movsb                   ;copy over next plane 2 pattern pixel
  333.         dec     di              ;stay at same address for next plane
  334.         mov     al,8            ;
  335.         out     dx,al           ;select plane 3 for writes
  336.         movsb                   ;copy over next plane 3 pattern pixel
  337.                                 ; and advance address
  338.         loop    @@DownloadPatternLoop
  339.  
  340.         mov        ax, @data
  341.         mov        ds,ax
  342.  
  343.         mov     dx,GC_INDEX     ;set the bit mask to select all bits
  344.         mov     ax,00000h+BIT_MASK ; from the latches and none from
  345.         out     dx,ax           ; the CPU, so that we can write the
  346.                                 ; latch contents directly to memory
  347.         mov     ax,StartY        ;top rectangle scan line
  348.         mov     si,ax
  349.         and     si,011b         ;top rect scan line modulo 4
  350.         add     si,_Pattern_Offset ;point to pattern scan line that
  351.                                 ; maps to top line of rect to draw
  352.         mov     dx,_Virtual_Width_Addr
  353.         mul     dx          ;offset in page of top rectangle scan line
  354.  
  355.         mov     di,StartX
  356.         mov     bx,di
  357.         shr     di,1        ;X/4 = offset of first rectangle pixel in scan
  358.         shr     di,1        ; line
  359.         add     di,ax       ;offset of first rectangle pixel in page
  360.         add     di,_Display_Offset     ;offset of first rectangle pixel in
  361.                                 ; display memory
  362.         and     bx,0003h                 ;look up left edge plane mask
  363.         mov     ah,LeftClipPlaneMask[bx] ; to clip
  364.         mov     bx,EndX
  365.         and     bx,0003h                  ;look up right edge plane
  366.         mov     al,RightClipPlaneMask[bx] ; mask to clip
  367.         mov     bx,ax                   ;put the masks in BX
  368.  
  369.         mov     cx,EndX            ;calculate # of addresses across rect
  370.         mov     ax,StartX
  371.         cmp     cx,ax
  372.         jle     @@FillDone        ;skip if 0 or negative width
  373.         dec     cx
  374.         and     ax,not 011b
  375.         sub     cx,ax
  376.         shr     cx,1
  377.         shr     cx,1        ;# of addresses across rectangle to fill - 1
  378.         jnz     @@MasksSet     ;there's more than one pixel to draw
  379.         and     bh,bl       ;there's only one pixel, so combine the left
  380.                             ; and right edge clip masks
  381. @@MasksSet:
  382.         mov     ax,EndY
  383.         sub     ax,StartY              ;AX = height of rectangle
  384.         jle     @@FillDone            ;skip if 0 or negative height
  385.         mov     Height,ax
  386.         mov     ax,_Virtual_Width_Addr
  387.         sub     ax,cx           ;distance from end of one scan line to start
  388.         dec     ax              ; of next
  389.         mov     NextScanOffset,ax
  390.         mov     RectAddrWidth,cx     ;remember width in addresses - 1
  391.         mov     dx,SC_INDEX+1         ;point to Sequence Controller Data reg
  392.                                     ; (SC Index still points to Map Mask)
  393. @@FillRowsLoop:
  394.         mov     cx,RectAddrWidth ;width across - 1
  395.         mov     al,es:[si]         ;read display memory to latch this scan
  396.                                 ; line's pattern
  397.         inc     si              ;point to the next pattern scan line, wrapping
  398.         jnz     short @@NoWrap     ; back to the start of the pattern if
  399.         sub     si,4            ; we've run off the end
  400. @@NoWrap:
  401.         mov     al,bh   ;put left-edge clip mask in AL
  402.         out     dx,al   ;set the left-edge plane (clip) mask
  403.         stosb           ;draw the left edge (pixels come from latches;
  404.                         ; value written by CPU doesn't matter)
  405.         dec     cx      ;count off left edge address
  406.         js      @@FillLoopBottom ;that's the only address
  407.         jz      @@DoRightEdge ;there are only two addresses
  408.         mov     al,00fh ;middle addresses are drawn 4 pixels at a pop
  409.         out     dx,al   ;set the middle pixel mask to no clip
  410.         rep     stosb   ;draw the middle addresses four pixels apiece
  411.                         ; (from latches; value written doesn't matter)
  412. @@DoRightEdge:
  413.         mov     al,bl   ;put right-edge clip mask in AL
  414.         out     dx,al   ;set the right-edge plane (clip) mask
  415.         stosb           ;draw the right edge (from latches; value
  416.                         ; written doesn't matter)
  417. @@FillLoopBottom:
  418.         add     di,NextScanOffset         ;point to the start of the next scan
  419.                                         ; line of the rectangle
  420.         dec     word ptr Height            ;count down scan lines
  421.         jnz     @@FillRowsLoop
  422. @@FillDone:
  423.         mov     dx,GC_INDEX+1 ;restore the bit mask to its default,
  424.         mov     al,0ffh       ; which selects all bits from the CPU
  425.         out     dx,al         ; and none from the latches (the GC
  426.                               ; Index still points to Bit Mask)
  427.  
  428.         pop        ds
  429.         pop     di
  430.         pop     si
  431.         mov     sp,bp
  432.         pop     bp
  433.         ret
  434. _RectangleFillPattern endp
  435.  
  436.  
  437.  
  438.  
  439.  
  440. ;----------------------------------------------------------------------------
  441. ; void RectangleFillPatternClip(int StartX, int StartY, int EndX, int EndY, PATTERN);
  442.  
  443.         public  _RectangleFillPatternClip
  444. _RectangleFillPatternClip proc    far
  445. ARG StartX:WORD, StartY:WORD, EndX:WORD, EndY:WORD, Pattern:DWORD
  446. LOCAL NextScanOffset:WORD, RectAddrWidth:WORD, Height:WORD = LocalStack
  447.         push    bp
  448.         mov     bp,sp
  449.         sub     sp,LocalStack
  450.         push    si
  451.         push    di
  452.         push     ds
  453.  
  454.  
  455.         ; clip it
  456.         ; yeah, it's may be kinda cheezy, but it's still fairly quick
  457.         ; (plus, it took about 5min :-])
  458. @@_ClipLeft:
  459.         mov        ax, StartX
  460.         cmp        ax, _ClipLeft
  461.         jg        @@_ClipRight
  462.         mov        ax, _ClipLeft
  463.         mov        StartX,ax
  464. @@_ClipRight:
  465.         mov        ax, EndX
  466.         cmp        ax, _ClipRight
  467.         jle        @@_ClipTop
  468.         mov        ax, _ClipRight
  469.         mov        EndX, ax
  470. @@_ClipTop:
  471.         mov        ax, StartY
  472.         cmp        ax, _ClipTop
  473.         jg        @@_ClipBottom
  474.         mov        ax, _ClipTop
  475.         mov        StartY, ax
  476. @@_ClipBottom:
  477.         mov        ax, EndY
  478.         cmp        ax, _ClipBottom
  479.         jle        @@ClipDone
  480.         mov        ax, _ClipBottom
  481.         mov        EndY, ax
  482.  
  483. @@ClipDone:
  484.         cld
  485.         mov     ax,_ModeX_Segment        ;point ES to display memory
  486.         mov     es,ax
  487.                                 ;copy pattern to display memory buffer
  488. ;        mov     si,Pattern         ;point to pattern to fill with
  489.         mov     di,_Pattern_Offset ;point ES:DI to pattern buffer
  490.         lds        si,Pattern
  491.         mov     dx,SC_INDEX     ;point Sequence Controller Index to
  492.         mov     al,MAP_MASK     ; Map Mask
  493.         out     dx,al
  494.         inc     dx              ;point to SC Data register
  495.         mov     cx,4            ;4 pixel quadruplets in pattern
  496. @@DownloadPatternLoop:
  497.         mov     al,1            ;
  498.         out     dx,al           ;select plane 0 for writes
  499.         movsb                   ;copy over next plane 0 pattern pixel
  500.         dec     di              ;stay at same address for next plane
  501.         mov     al,2            ;
  502.         out     dx,al           ;select plane 1 for writes
  503.         movsb                   ;copy over next plane 1 pattern pixel
  504.         dec     di              ;stay at same address for next plane
  505.         mov     al,4            ;
  506.         out     dx,al           ;select plane 2 for writes
  507.         movsb                   ;copy over next plane 2 pattern pixel
  508.         dec     di              ;stay at same address for next plane
  509.         mov     al,8            ;
  510.         out     dx,al           ;select plane 3 for writes
  511.         movsb                   ;copy over next plane 3 pattern pixel
  512.                                 ; and advance address
  513.         loop    @@DownloadPatternLoop
  514.  
  515.         mov        ax, @data
  516.         mov        ds,ax
  517.  
  518.         mov     dx,GC_INDEX     ;set the bit mask to select all bits
  519.         mov     ax,00000h+BIT_MASK ; from the latches and none from
  520.         out     dx,ax           ; the CPU, so that we can write the
  521.                                 ; latch contents directly to memory
  522.         mov     ax,StartY        ;top rectangle scan line
  523.         mov     si,ax
  524.         and     si,011b             ;top rect scan line modulo 4
  525.         add     si,_Pattern_Offset     ;point to pattern scan line that
  526.                                     ; maps to top line of rect to draw
  527.         mov     dx,_Virtual_Width_Addr
  528.         mul     dx          ;offset in page of top rectangle scan line
  529.         mov     di,StartX
  530.         mov     bx,di
  531.         shr     di,1        ;X/4 = offset of first rectangle pixel in scan
  532.         shr     di,1        ; line
  533.         add     di,ax       ;offset of first rectangle pixel in page
  534.         add     di,_Display_Offset     ;offset of first rectangle pixel in
  535.                                 ; display memory
  536.         and     bx,0003h                 ;look up left edge plane mask
  537.         mov     ah,LeftClipPlaneMask[bx] ; to clip
  538.         mov     bx,EndX
  539.         and     bx,0003h                  ;look up right edge plane
  540.         mov     al,RightClipPlaneMask[bx] ; mask to clip
  541.         mov     bx,ax                   ;put the masks in BX
  542.  
  543.         mov     cx,EndX            ;calculate # of addresses across rect
  544.         mov     ax,StartX
  545.         cmp     cx,ax
  546.         jle     @@FillDone        ;skip if 0 or negative width
  547.         dec     cx
  548.         and     ax,not 011b
  549.         sub     cx,ax
  550.         shr     cx,1
  551.         shr     cx,1        ;# of addresses across rectangle to fill - 1
  552.         jnz     @@MasksSet     ;there's more than one pixel to draw
  553.         and     bh,bl       ;there's only one pixel, so combine the left
  554.                             ; and right edge clip masks
  555. @@MasksSet:
  556.         mov     ax,EndY
  557.         sub     ax,StartY              ;AX = height of rectangle
  558.         jle     @@FillDone            ;skip if 0 or negative height
  559.         mov     Height,ax
  560.         mov     ax,_Virtual_Width_Addr
  561.         sub     ax,cx           ;distance from end of one scan line to start
  562.         dec     ax              ; of next
  563.         mov     NextScanOffset,ax
  564.         mov     RectAddrWidth,cx     ;remember width in addresses - 1
  565.         mov     dx,SC_INDEX+1         ;point to Sequence Controller Data reg
  566.                                     ; (SC Index still points to Map Mask)
  567. @@FillRowsLoop:
  568.         mov     cx,RectAddrWidth ;width across - 1
  569.         mov     al,es:[si]         ;read display memory to latch this scan
  570.                                 ; line's pattern
  571.         inc     si              ;point to the next pattern scan line, wrapping
  572.         jnz     short @@NoWrap     ; back to the start of the pattern if
  573.         sub     si,4            ; we've run off the end
  574. @@NoWrap:
  575.         mov     al,bh   ;put left-edge clip mask in AL
  576.         out     dx,al   ;set the left-edge plane (clip) mask
  577.         stosb           ;draw the left edge (pixels come from latches;
  578.                         ; value written by CPU doesn't matter)
  579.         dec     cx      ;count off left edge address
  580.         js      @@FillLoopBottom ;that's the only address
  581.         jz      @@DoRightEdge ;there are only two addresses
  582.         mov     al,00fh ;middle addresses are drawn 4 pixels at a pop
  583.         out     dx,al   ;set the middle pixel mask to no clip
  584.         rep     stosb   ;draw the middle addresses four pixels apiece
  585.                         ; (from latches; value written doesn't matter)
  586. @@DoRightEdge:
  587.         mov     al,bl   ;put right-edge clip mask in AL
  588.         out     dx,al   ;set the right-edge plane (clip) mask
  589.         stosb           ;draw the right edge (from latches; value
  590.                         ; written doesn't matter)
  591. @@FillLoopBottom:
  592.         add     di,NextScanOffset         ;point to the start of the next scan
  593.                                         ; line of the rectangle
  594.         dec     word ptr Height            ;count down scan lines
  595.         jnz     @@FillRowsLoop
  596. @@FillDone:
  597.         mov     dx,GC_INDEX+1 ;restore the bit mask to its default,
  598.         mov     al,0ffh       ; which selects all bits from the CPU
  599.         out     dx,al         ; and none from the latches (the GC
  600.                               ; Index still points to Bit Mask)
  601.  
  602.         pop        ds
  603.         pop     di
  604.         pop     si
  605.         mov     sp,bp
  606.         pop     bp
  607.         ret
  608. _RectangleFillPatternClip endp
  609.  
  610.  
  611. ;----------------------------------------------------------------------------
  612. ;void ClearClipPort() {
  613. ;    RectangleFill(ClipLeft, ClipTop, ClipRight, ClipBottom);
  614. ;}
  615.  
  616.     public _ClearClipPort
  617. _ClearClipPort proc
  618.     push    ds
  619.     mov        ax,@data
  620.     mov        ds,ax
  621.  
  622.     xor        ax,ax
  623.     push    ax                    ;push the color (black)
  624.     mov        ax,_ClipBottom
  625.     push    ax
  626.     mov        ax,_ClipRight
  627.     dec        ax
  628.     push    ax
  629.     mov        ax,_ClipTop
  630.     push    ax
  631.     mov        ax,_ClipLeft
  632.     push    ax
  633.     call    _RectangleFillAligned
  634.     pop        ax
  635.     pop        ax
  636.     pop        ax
  637.     pop        ax
  638.     pop        ax
  639.     pop        ds
  640.     ret
  641. _ClearClipPort endp
  642.  
  643.  
  644. ;----------------------------------------------------------------------------
  645. ;void ClearVirtualPort() {
  646. ;    RectangleFill(0, 0, Virtual_Width, Virtual_Height, BLACK);
  647. ;}
  648.     public _ClearVirtualPort
  649. _ClearVirtualPort proc
  650.     push    ds
  651.     mov        ax,@data
  652.     mov        ds,ax
  653.  
  654.     xor        ax,ax
  655.     push    ax                    ;push color
  656.     mov        bx,_Virtual_Height_Pix
  657.     push    bx
  658.     mov        bx,_Virtual_Width_Pix
  659.     dec        bx
  660.     push    bx
  661.     push    ax
  662.     push    ax
  663.     call    _RectangleFillAligned
  664.     pop        ax
  665.     pop        ax
  666.     pop        ax
  667.     pop        ax
  668.     pop        ax
  669.     pop        ds
  670.     ret
  671. _ClearVirtualPort endp
  672.  
  673.  
  674. ;----------------------------------------------------------------------------
  675. END